package com.ycxy.sh.transaction.service.impl;

import com.ycxy.sh.transaction.dao.dto.UserInfoStandardDTO;
import com.ycxy.sh.transaction.dao.entity.Commodity;
import com.ycxy.sh.transaction.dao.entity.Login;
import com.ycxy.sh.transaction.dao.entity.UserInfo;
import com.ycxy.sh.transaction.dao.vo.LayuiPageVo;
import com.ycxy.sh.transaction.dao.vo.UserInfoAvatarVo;
import com.ycxy.sh.transaction.dao.vo.UserInfoStandardVo;
import com.ycxy.sh.transaction.ex.ServiceException;
import com.ycxy.sh.transaction.mapper.CommodityMapper;
import com.ycxy.sh.transaction.mapper.LoginMapper;
import com.ycxy.sh.transaction.mapper.UserInfoMapper;
import com.ycxy.sh.transaction.service.UserInfoService;
import com.ycxy.sh.transaction.util.GetCode;
import com.ycxy.sh.transaction.util.JsonReader;
import com.ycxy.sh.transaction.util.JustPhone;
import com.ycxy.sh.transaction.util.SmsUtil;
import com.ycxy.sh.transaction.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: 宋H
 * @Date: 2023/3/29
 * @Description: com.ycxy.sh.transaction.service
 * @version: 1.0
 */
@Service
@Slf4j
public class UserInfoServiceImpl implements UserInfoService {

    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private CommodityMapper commodityMapper;

    /**手机号和更换手机号验证码map集合*/
    private static Map<String, String> phonecodemap = new HashMap<>();

    /**
     * 修改密码
     * @param session
     * @param request
     */
    public void updatePassword(HttpSession session, HttpServletRequest request) throws IOException {
        log.debug("开始处理修改密码的业务...");
        JSONObject json = JsonReader.receivePost(request);
        String oldpwd = json.getString("oldpwd");
        String newpwd = json.getString("newpwd");
        Long userid = (Long) session.getAttribute("userid");
        Login login = new Login();
        UserInfo userInfo = new UserInfo();
        login.setUserId(userid);
        //判断用户是否存在
        Login login1 = loginMapper.userLogin(login);
        String oldpwds = new Md5Hash(oldpwd, "Secondhand-shops").toString();
        //如果旧密码相等
        if (oldpwds.equals(login1.getPassword())){
            //盐加密
            String passwords = new Md5Hash(newpwd, "Secondhand-shops").toString();
            login.setPassword(passwords);
            //设置新密码
            userInfo.setPassword(passwords).setUserId(login1.getUserId());
            //修改用户登录信息
            Integer integer = loginMapper.updateLogin(login);
            //修改用户信息
            Integer integer1 = userInfoMapper.Update(userInfo);
            if (integer < 1 || integer1 < 1) {
                String message="修改密码失败";
                log.debug(message);
                throw new ServiceException(ServiceCode.ERR_UPDATE,message);
            }
        }
        throw new ServiceException(ServiceCode.ERR_CONFLICT,"当前密码错误");
    }

    /**
     * 查询用户头像
     * @param session
     */
    @Override
    public UserInfoAvatarVo selectUserAvatar(HttpSession session) {
        log.debug("开始处理查询用户头像的业务...");
        Long userid = (Long) session.getAttribute("userid");
        //查询用户头像
        UserInfoAvatarVo userInfo = userInfoMapper.selectPartInfo(userid);
        return userInfo;
    }

    /**
     * 修改头像
     * @param file
     * @param session
     * @return
     */
    @Override
    public JSONObject updateUserimage(MultipartFile file, HttpSession session) throws IOException {
        log.debug("开始处理修改头像的业务...");
        JSONObject res = new JSONObject();
        JSONObject resUrl = new JSONObject();
        String filename = UUID.randomUUID().toString().replaceAll("-", "");
        String ext = FilenameUtils.getExtension(file.getOriginalFilename());//获得文件扩展名
        String filenames = filename + "." + ext;//文件全名
        String pathname = "D:/dn-img" + filenames;
        file.transferTo(new File(pathname));
        resUrl.put("src", "/pic/"+filenames);
        res.put("msg", "");
        res.put("code", 0);
        res.put("data", resUrl);
        String uimgUrl = "/pic/" + filenames;

        //获取session中的用户id
        Long userid=(Long) session.getAttribute("userid");
        UserInfo userInfo = new UserInfo().setUserId(userid).setUserImage(uimgUrl);
        //修改用户信息
        int row = userInfoMapper.Update(userInfo);
        if(row!=1){
            String message="修改用户信息失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
        return res;
    }

    /**
     * 根据用户id查看个人信息
     * @param session
     */
    @Override
    public UserInfoStandardVo selectUserInfo(HttpSession session) {
        log.debug("开始处理根据用户id查看个人信息的业务...");
        Long userid = (Long) session.getAttribute("userid");
        UserInfoStandardVo userInfo = userInfoMapper.selectUserinfo(userid);
        if(userInfo==null){
            String message="用户信息不存在";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        return userInfo;
    }

    /**
     * 根据用户id修改个人信息
     *
     * @param userInfoStandardDTO
     * @param session
     */
    @Override
    public void updateInfo(UserInfoStandardDTO userInfoStandardDTO, HttpSession session) {
        log.debug("开始处理根据用户id修改个人信息的业务...");
        String username = userInfoStandardDTO.getUsername();
        Long userid = (Long) session.getAttribute("userid");
        Login login = new Login();
        //如果传入用户名
        if (!StringUtils.isEmpty(username)){
            login.setUsername(username);
            //判断用户是否存在
            Login login1 = loginMapper.userLogin(login);
            //如果该用户名对应的有用户
            if (!StringUtils.isEmpty(login1)){
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "该用户名已存在");
            }
            //否则设置用户id，修改用户信息
            login.setUserId(userid);
            //修改登录表中用户名
            loginMapper.updateLogin(login);
        }
        userInfoStandardDTO.setUserId(userid);
        Integer integer1 = userInfoMapper.updateUserInfo(userInfoStandardDTO);
        if (integer1 != 1) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "个人信息修改失败");
        }
    }

    /**
     * 更换手机号时发送短信验证码
     * @param request
     * @throws IOException
     */
    @Override
    public void sendUpdatePhone(HttpServletRequest request) throws IOException {
        JSONObject json = JsonReader.receivePost(request);
        final String mobilephone = json.getString("mobilephone");
        Integer type = json.getInt("type");
        Login login = new Login();
        if(type!=2){
            throw new ServiceException(ServiceCode.ERR_FORBIDDEN, "违规操作");
        }
        if (!JustPhone.justPhone(mobilephone)) {//判断输入的手机号格式是否正确
            throw new ServiceException(ServiceCode.ERR_CONFLICT, "请输入正确格式的手机号");
        }
        //查询手机号是否存在
        login.setMobilePhone(mobilephone);
        Login userIsExist = loginMapper.userLogin(login);
        if (!StringUtils.isEmpty(userIsExist)){//若手机号已注册过
            throw new ServiceException(ServiceCode.ERR_CONFLICT, "手机号已存在");
        }
        String code = GetCode.phonecode();
        Integer result = new SmsUtil().SendMsg(mobilephone, code, type);//发送验证码
        if(result == 1) {//发送成功
            phonecodemap.put(mobilephone, code);//放入map集合进行对比
/*
            final Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    phonecodemap2.remove(phoneNum);
                    timer.cancel();
                }
            }, 5 * 60 * 1000);
*/
            //执行定时任务
            ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
                    new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
            executorService.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    phonecodemap.remove(mobilephone);
                    ((ScheduledThreadPoolExecutor) executorService).remove(this::run);
                }
            },5 * 60 * 1000,5 * 60 * 1000, TimeUnit.HOURS);
            log.debug("验证码发送成功");
        }else if(result == 2){
            throw new ServiceException(ServiceCode.ERR_CONFLICT,"请输入正确格式的手机号");
        }
        throw new ServiceException(ServiceCode.ERR_FORBIDDEN,"验证码发送失败");
    }

    /**
     * 修改绑定手机号
     * @param mobilephone
     * @param vercode
     * @param session
     */
    @Override
    public void updatePhone(String mobilephone, String vercode, HttpSession session) {
        Long userid = (Long) session.getAttribute("userid");
        String rel = phonecodemap.get(mobilephone);
        if (StringUtils.isEmpty(rel)) {//验证码到期 或者 没发送短信验证码
            throw new ServiceException(ServiceCode.ERR_CONFLICT,"请重新获取验证码");
        }
        if (rel.equalsIgnoreCase(vercode)) {//验证码正确
            Login login = new Login().setUserId(userid).setMobilePhone(mobilephone);
            UserInfo userInfo = new UserInfo().setUserId(userid).setMobilePhone(mobilephone);
            Integer integer = loginMapper.updateLogin(login);
            Integer integer1 = userInfoMapper.Update(userInfo);
            if (integer < 1 || integer1 < 1) {
                throw new ServiceException(ServiceCode.ERR_CONFLICT,"系统错误，更换失败");
            }
           log.debug("验证码发送成功");
        }
        throw new ServiceException(ServiceCode.ERR_CONFLICT,"验证码错误");
    }

    /**
     * 根据用户id查询个人简介
     * @param userid
     */
    @Override
    public void userBriefIntroduction(Long userid) {
        UserInfoStandardVo userInfoStandardVo = userInfoMapper.selectUserinfo(userid);
        if (StringUtils.isEmpty(userInfoStandardVo)){
            String message="查询成功";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,"验证码错误");
        }
    }

    @Override
    public LayuiPageVo userHomeCommodity(Long userid, int limit, int page) {
        List<Commodity> commodityList = commodityMapper.queryAllCommodity((page - 1) * limit, limit, userid,1);
        Integer dataNumber = commodityMapper.queryCommodityCount(userid,1);
        return new LayuiPageVo("", 0,dataNumber,commodityList);
    }
    /**修改用户信息*/
    @Override
    public int UpdateUserInfo(UserInfo userInfo){
        return userInfoMapper.Update(userInfo);
    }

}
